package com.zxh.blog.util.excelDemo;

import com.zxh.blog.util.excel.StringConvertUtils;
import org.apache.commons.beanutils.ConvertUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @Author:wb-zxh410423
 * @Description: excel数据
 * @Date: Created in 11:02 2018/12/11
 */
public class ExcelData<T> {
	/**
	 * 列头
	 */
	private List<String> headerRow;

	/**
	 * excel对应的类对象的列配置
	 */
	private ExcelColumnsConfigMap excelColumnsConfigMap;

	/**
	 *数据
	 */
	private List<T> dataList = new ArrayList<T>();

	/**
	 * 用于读取excel的构造器
	 * 初始化表头和列配置
	 * @param headerRow
	 * @param tClass
	 */
	ExcelData(List<String> headerRow,Class<T> tClass){
		this.headerRow = headerRow;
		excelColumnsConfigMap = ExcelColumnsConfigMap.parse(tClass);
	}

	/**
	 * 用于写excel的构造器
	 * 初始化列配置信息
	 * @param tClass
	 * @param dataList
	 */
	ExcelData(Class<T> tClass,List<T> dataList){
		excelColumnsConfigMap = ExcelColumnsConfigMap.parse(tClass);
		this.headerRow = excelColumnsConfigMap.getHeaderName();
		this.dataList = dataList;
	}

	/**
	 * 添加一行数据
	 * @param dataRowCellValues
	 * @param tClass
	 * @param rowNum
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	void addData(List<String> dataRowCellValues, Class<T> tClass, int rowNum) throws InstantiationException, IllegalAccessException {
		T data = this.parseRow(dataRowCellValues, tClass, rowNum);
		dataList.add(data);
	}

	/**
	 * 获取excel String数据
	 * @return
	 */
	List<List<String>> getRows(Class<T> tClass) {
		List<List<String>> rows = new ArrayList<List<String>>();
		dataList.forEach(e -> rows.add(getRow(tClass, e)));
		return rows;
	}

	/**
	 * 获取一行的数据
	 * @param tClass
	 * @param data
	 * @return
	 */
	private List<String> getRow(Class<T> tClass, T data) {
		List<String> row = new ArrayList<>();
		headerRow.forEach(e -> {

			Optional<ExcelColumnConfigModel> fieldName = excelColumnsConfigMap.getConfig(e);
			Optional<Field> fieldOpt = ReflectUtils.getField(tClass, fieldName.get().getName());

			Field field = fieldOpt.get();
			field.setAccessible(true);
			String valueStr = "";
			try {
				Object value = field.get(data);
				if (null != value) {
					valueStr = ConvertUtils.convert(value);
				}
			} catch (IllegalAccessException e1) {
			}
			row.add(valueStr);
		});
		return row;
	}

	/**
	 * 解析数据
	 * @param dataRowCellValues
	 * @param tClass
	 * @return
	 */
	private T parseRow(List<String> dataRowCellValues, Class<T> tClass, int rowNum) throws IllegalAccessException, InstantiationException {

		T dataObject = tClass.newInstance();
		for (int i = 0; i < dataRowCellValues.size(); i++) {
			Optional<ExcelColumnConfigModel> configResult = this.excelColumnsConfigMap.getConfig(headerRow.get(i));

			ExcelColumnConfigModel config = configResult.get();
			String fieldStringValue = dataRowCellValues.get(i);
			//检查2（插入检查）：如果导入操作不是更新操作（而是插入操作），则需要检查要求不能为空的字段是否确实不为空
			if (!config.canEmpty()) {
			}

			String fieldName = config.getName();
			Optional<Field> fieldOpt = ReflectUtils.getField(tClass, fieldName);

			Field field = fieldOpt.get();
			field.setAccessible(true);
			Class<?> fieldType = field.getType();

			Object fieldRealTypeValue = null;
			if (fieldStringValue != null) {
				fieldRealTypeValue = StringConvertUtils.convert(fieldStringValue, fieldType);
			}
			//此次注意类型异常
			field.set(dataObject, fieldRealTypeValue);
		}
		return dataObject;
	}

	/**
	 * Getter method for property dataList.
	 *
	 * @return property value of dataList
	 */
	public List<T> getDataList() {
		return dataList;
	}

	/**
	 * Getter method for property headerRow.
	 *
	 * @return property value of headerRow
	 */
	public List<String> getHeaderRow() {
		return headerRow;
	}
}

